//
//  UIViewAdditions.m
//  Tint
//
//  Created by Kevin Wu on 2/22/12.
//  Copyright (c) 2012 Telligenty. All rights reserved.
//

#import "UIViewAdditions.h"


@implementation UIView (Tint)


#pragma mark - Accessors

- (CGFloat)leftX
{
    return self.frame.origin.x;
}
- (void)setLeftX:(CGFloat)leftX
{
    [self setFrameIfNeeded:TTRectSetX(self.frame, leftX)];
}

- (CGFloat)centerX
{
    return self.center.x;
}
- (void)setCenterX:(CGFloat)centerX
{
    [self setCenterIfNeeded:TTPointSetX(self.center, centerX)];
}

- (CGFloat)rightX
{
    return self.frame.origin.x + self.frame.size.width;
}
- (void)setRightX:(CGFloat)rightX
{
    [self setFrameIfNeeded:TTRectSetX(self.frame, rightX - self.frame.size.width)];
}


- (CGFloat)topY
{
    return self.frame.origin.y;
}
- (void)setTopY:(CGFloat)topY
{
    [self setFrameIfNeeded:TTRectSetY(self.frame, topY)];
}

- (CGFloat)centerY
{
    return self.center.y;
}
- (void)setCenterY:(CGFloat)centerY
{
    [self setCenterIfNeeded:TTPointSetY(self.center, centerY)];
}

- (CGFloat)bottomY
{
    return self.frame.origin.y + self.frame.size.height;
}
- (void)setBottomY:(CGFloat)bottomY
{
    [self setFrameIfNeeded:TTRectSetY(self.frame, bottomY-self.frame.size.height)];
}



- (CGFloat)width
{
    return self.frame.size.width;
}
- (void)setWidth:(CGFloat)width
{
    [self setFrameIfNeeded:TTRectSetWidth(self.frame, width)];
}

- (CGFloat)height
{
    return self.frame.size.height;
}
- (void)setHeight:(CGFloat)height
{
    [self setFrameIfNeeded:TTRectSetHeight(self.frame, height)];
}



- (CGPoint)origin
{
    return self.frame.origin;
}
- (void)setOrigin:(CGPoint)origin
{
    [self setFrameIfNeeded:TTRectSetOrigin(self.frame, origin)];
}

- (CGSize)size
{
    return self.frame.size;
}
- (void)setSize:(CGSize)size
{
    [self setFrameIfNeeded:TTRectSetSize(self.frame, size)];
}



#pragma mark - Adding and removing subview

- (void)addCenteredSubview:(UIView *)subview
{
    if ( subview.superview != self ) {
        [self addSubview:subview];
    }
    [subview moveToCenterOfSuperview];
}

- (void)removeAllSubviews
{
    [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}



#pragma mark - Rendering image

- (UIImage *)viewAsImage
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [[UIScreen mainScreen] scale]);
	[self.layer renderInContext:UIGraphicsGetCurrentContext()];
	UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // AUTO
	UIGraphicsEndImageContext();
	return image;
}



#pragma mark - Placing

- (void)occupySuperview
{
    if ( self.superview ) {
        [self setFrameIfNeeded:self.superview.bounds];
    }
}

- (void)moveToCenterOfSuperview
{
    if ( self.superview ) {
        CGRect frm = TTRectMake((self.superview.frame.size.width - self.frame.size.width) / 2.0, 
                                (self.superview.frame.size.height - self.frame.size.height) / 2.0, 
                                self.frame.size.width, 
                                self.frame.size.height);
        [self setFrameIfNeeded:frm];
    }
}

- (void)moveToVerticalCenterOfSuperview
{
    if ( self.superview ) {
        CGRect frm = TTRectMake(self.frame.origin.x, 
                                (self.superview.frame.size.height - self.frame.size.height) / 2.0, 
                                self.frame.size.width, 
                                self.frame.size.height);
        [self setFrameIfNeeded:frm];
    }
}

- (void)moveToHorizontalCenterOfSuperview
{
    if ( self.superview ) {
        CGRect frm = TTRectMake((self.superview.frame.size.width - self.frame.size.width) / 2.0, 
                                self.frame.origin.y, 
                                self.frame.size.width, 
                                self.frame.size.height);
        [self setFrameIfNeeded:frm];
    }
}

- (void)setFrameIfNeeded:(CGRect)frame
{
    if ( !CGRectEqualToRect(self.frame, frame) ) {
        self.frame = frame;
    }
}

- (void)setCenterIfNeeded:(CGPoint)center
{
    if ( !CGPointEqualToPoint(self.center, center) ) {
        self.center = center;
    }
}



#pragma mark - Finding views

- (UIViewController *)findViewController
{
    for ( UIView *next=self; next; next=next.superview ) {
        UIResponder *nextResponder = [next nextResponder];
        if ( TTIsInstance(nextResponder, [UIViewController class]) ) {
            return (UIViewController *)nextResponder;
        }
    }
    return nil;
}

- (UIView *)findFirstResponder
{
    return TTFindFirstResponderInView(self);
}

- (NSArray *)newSuperviewsArray
{
    NSMutableArray *superviews = nil;
    
    if ( self.superview ) {
        superviews = [[NSMutableArray alloc] init];
        UIView *view = self;
        while ( view.superview ) {
            [superviews addObject:view.superview];
            view = view.superview;
        }
    }
    return superviews;
}

- (NSArray *)newSubviewsArrayWithClass:(Class)cls
{
    NSMutableArray *views = nil;
    if ( [self.subviews count] > 0 ) {
        views = [[NSMutableArray alloc] init];
        for ( int i=0; i<[self.subviews count]; ++i ) {
            UIView *child = [self.subviews objectAtIndex:i];
            if ( [child isKindOfClass:cls] ) {
                [views addObject:child];
            }
        }
    }
    return views;
}

- (UIView *)descendantOrSelfWithClass:(Class)cls
{
    if ( [self isKindOfClass:cls] ) {
        return self;
    }
    
    for ( UIView *child in self.subviews ) {
        UIView *it = [child descendantOrSelfWithClass:cls];
        if ( it ) {
            return it;
        }
    }
    
    return nil;
}

- (UIView *)ancestorOrSelfWithClass:(Class)cls
{
    if ( [self isKindOfClass:cls] ) {
        return self;
    } else if ( self.superview ) {
        return [self.superview ancestorOrSelfWithClass:cls];
    }
    return nil;
}



#pragma mark - Hierarchy

- (UIView *)rootView
{
    UIView *view = self;
    while ( view.superview ) {
        view = view.superview;
    }
    return view;
}

- (void)bringToFront
{
	[self.superview bringSubviewToFront:self];
}

- (void)sendToBack
{
	[self.superview sendSubviewToBack:self];
}

- (BOOL)isInFront
{
	return ( [self.superview.subviews lastObject] == self );
}

- (BOOL)isAtBack
{
    NSArray *array = self.superview.subviews;
    if ( [array count] > 0 ) {
        return ( [array objectAtIndex:0] == self );
    }
    return NO;
}


#pragma mark - Debug

- (void)showBorderWithRedColor
{
#ifdef DEBUG
    [self showBorderWithColor:[UIColor redColor]];
#endif
}

- (void)showBorderWithGreenColor
{
#ifdef DEBUG
    [self showBorderWithColor:[UIColor greenColor]];
#endif
}

- (void)showBorderWithBlueColor
{
#ifdef DEBUG
    [self showBorderWithColor:[UIColor blueColor]];
#endif
}

- (void)showBorderWithBlackColor
{
#ifdef DEBUG
    [self showBorderWithColor:[UIColor blackColor]];
#endif
}

- (void)showBorderWithColor:(UIColor *)color
{
#ifdef DEBUG
    self.layer.borderColor = color.CGColor;
	self.layer.borderWidth = 1.0;
#endif
}

+ (void)showBorder:(UIView *)view withColor:(UIColor *)color
{
#ifdef DEBUG
    static NSArray *colors = nil;
    
    if ( colors == nil ) {
        colors = [[NSArray alloc] initWithObjects:
                  [UIColor redColor],
                  [UIColor greenColor],
                  [UIColor blueColor],
                  [UIColor blackColor],
                  [UIColor brownColor],
                  [UIColor purpleColor], nil];
    }
    
    UIColor *currentColor = color;
    UIColor *nextColor = nil;
    
    if ( currentColor == nil ) {
        currentColor = [colors objectAtIndex:0];
    }
    
    for ( int i=0; i<[colors count]; ++i ) {
        UIColor *tmp = [colors objectAtIndex:i];
        if ( tmp == currentColor ) {
            if ( (i+1) < [colors count] ) {
                nextColor = [colors objectAtIndex:i+1];
            } else {
                nextColor = [colors objectAtIndex:0];
            }
        }
    }
    
    
    [view showBorderWithColor:currentColor];
    
    for ( int i=0; i<[view.subviews count]; ++i ) {
        UIView *child = [view.subviews objectAtIndex:i];
        [self showBorder:child withColor:nextColor];
    }
    
#endif
}

+ (void)dumpView:(UIView *)view level:(NSInteger)level
{
#ifdef DEBUG
    NSMutableString *space = [[NSMutableString alloc] init];
    for ( int j=0; j<level; ++j ) {
        [space appendString:@"|_"];
    }
    
    NSLog(@"%@%d:%@ subview:%d retain:%d frame:%@", 
          space, 
          level, 
          NSStringFromClass([view class]), 
          [view.subviews count], 
          [view retainCount], 
          NSStringFromCGRect(view.frame));
    [space release];
    
    
    for ( int i=0; i<[view.subviews count]; ++i ) {
        UIView *child = [view.subviews objectAtIndex:i];
        [self dumpView:child level:(level + 1)];
    }
#endif
}

@end
